<script setup lang="ts">
import type { EntityBaseInfo, SevenCode } from "@@/apis/entity/type"
import type { UploadUserFile, UploadProps } from "element-plus"
import type { FormInstance, FormRules } from "element-plus"
import { getEntityInfoApi, updateEntityDataApi, uploadEntityFilesApi } from "@@/apis/entity"
import { useFetchSevenCode } from "@@/apis/sevencode/useFetchSevenCode"
import SelectTag from "@@/components/SelectTag/index.vue"
import SelectThree from "@@/components/SelectThreeMilstd/index.vue"
import SelectMilstd from "@@/components/SelectThreeMilstd/index.vue"
import { ElMessage, ElMessageBox } from "element-plus"
import { cloneDeep, isEqual } from "lodash-es"
import { computed, nextTick, onMounted, ref, watch } from "vue"

const props = defineProps<Props>()

const emit = defineEmits(["closeDialog"])

const {
  kindOptions,
  domainOptions,
  countryOptions,
  categoryOptions,
  subCategoryOptions,
  specificOptions,
  extraOptions,
  sevencode,
  loading: sevenCodeLoading,
  kindChange,
  domainChange,
  countryChange,
  categoryChange,
  subcategoryChange,
  specificChange,
  extraChange
} = useFetchSevenCode()

const drawer = ref(false)
interface Props {
  id: string | undefined
  visible: boolean
}
const DEFAULT_SEVENCODE: SevenCode = {
  kind: -1,
  domain: -1,
  country: -1,
  category: -1,
  subcategory: -1,
  specific: -1,
  extra: -1
}
const DEFAULT_FORM_DATA: EntityBaseInfo = {
  id: props.id,
  code: "",
  name: "",
  tag: [],
  description: "",
  milstdId: "",
  threeId: "",
  entityType: cloneDeep(DEFAULT_SEVENCODE)
}
const dialogVisible = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<EntityBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))
const tagList = ref<any[]>([])
const tagLoading = ref<boolean>(false)
const newTagInput = ref("")

const formRules: FormRules<EntityBaseInfo> = {
  "code": [{ required: true, trigger: "blur", message: "请输入" }],
  "entityType.kind": [{ required: true, trigger: "change", message: "请选择" }],
  "entityType.domain": [{ required: true, trigger: "change", message: "请选择" }],
  "entityType.country": [{ required: true, trigger: "change", message: "请选择" }],
  "entityType.category": [{ required: true, trigger: "change", message: "请选择" }],
  "entityType.subcategory": [{ required: true, trigger: "change", message: "请选择" }],
  "entityType.specific": [{ required: true, trigger: "change", message: "请选择" }],
  "entityType.extra": [{ required: true, trigger: "change", message: "请选择" }]
}

const loading = ref<boolean>(false)
const detailLoading = ref<boolean>(false)
const defData = ref<EntityBaseInfo | undefined>(undefined)
const insertFiles = ref([])

function showDialog() {
  formRef.value?.resetFields()
  detailLoading.value = false
  getEntityInfo()
}
function getEntityInfo() {
  if (!props.id) return

  detailLoading.value = true
  getEntityInfoApi(props.id)
    .then(({ data }) => {
      formData.value = cloneDeep(data.entity)
      try {
        formData.value.tag = Array.isArray(formData.value.tag)
          ? formData.value.tag
          : (typeof formData.value.tag === "string" ? JSON.parse(formData.value.tag) : [])
      } catch (e) {
        console.error("解析标签数据失败:", e)
        formData.value.tag = []
      }

      const entityType: SevenCode = {
        kind: Number(data.entityType.kind),
        domain: Number(data.entityType.domain),
        country: Number(data.entityType.country),
        category: Number(data.entityType.category),
        subcategory: Number(data.entityType.subcategory),
        specific: Number(data.entityType.specific),
        extra: Number(data.entityType.extra)
      }

      formData.value.entityType = cloneDeep(entityType)

      nextTick(() => {
        updateSevencode(entityType)
      })
      data.files.forEach((item: any) => {
        item.name = item.fileName
        item.url = item.filePath
      })
      insertFiles.value = data.files

      defData.value = cloneDeep(formData.value)
    })
    .finally(() => {
      detailLoading.value = false
    })
}
function updateSevencode(data: SevenCode) {
  sevencode.value = cloneDeep(data)
}
function syncSevencodeToForm() {
  formData.value.entityType = cloneDeep(sevencode.value)
}
function handleCloseTip(done: () => void) {
  // 校验值是否相同
  if (isEqual(defData.value, formData.value)) {
    closeDialog()
    done()
    return
  }
  ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
    done()
  })
}
function closeDialog() {
  formRef.value?.resetFields()
  emit("closeDialog", undefined)
}
function closeDialogTag() {
  drawer.value = false
}
// 编辑确定

function handleConfirm() {
  loading.value = true
  formRef.value?.validate(async (valid: boolean) => {
    if (!valid) {
      loading.value = false
      return
    }
    keepFile()
  })
}
// 上传文件
const handleFileChange: UploadProps["onChange"] = (file: any, fileList: any) => {
  insertFiles.value = fileList
}

// 保存文件接口
const keepFile = () => {
  const newFiles = insertFiles.value.filter(item => !item.id)
  const fd = new FormData()
  newFiles.forEach((item: any, index: any) => {
    fd.append(`insertFiles[${index}].file`, item.raw)
  })
  fd.append("businessId", props.id as string)
  removeFile.value.forEach((item: any, index: any) => {
    fd.append(`removeFiles[${index}].id`, item)
  })
  // 先保存文件，再保存基本信息，保证查看附件能显示出来
  syncSevencodeToForm()
  const submitData = cloneDeep(formData.value)
  submitData.tag = Array.isArray(submitData.tag)
    ? JSON.stringify(submitData.tag)
    : JSON.stringify([])
  const fd2 = new FormData()
  fd2.append("businessParam", JSON.stringify(submitData))
  uploadEntityFilesApi(fd).then((res: any) => {
    updateEntityDataApi(fd2).then(() => {
      ElMessage.success("保存成功")
      closeDialog()
    }).finally(() => {
      loading.value = false
    })
  })
}
// 删除文件
const removeFile = ref<string[]>([])
function handleRemove(uploadFile: any, uploadFiles: any) {
  if (uploadFile.id) {
    removeFile.value.push(uploadFile.id)
  } else {
    /// 如果是新上传的文件，从 insertFiles 中删除
    const index = insertFiles.value.findIndex((file: any) => file.raw === uploadFile.raw)
    if (index !== -1) {
      insertFiles.value.splice(index, 1) // 从 insertFiles 中删除新上传的文件
    }
  }
}
watch(() => props.visible, (val) => {
  dialogVisible.value = val
  if (val) {
    // 打开抽屉清空存放删除id数组
    removeFile.value = []
    showDialog()
  }
})
watch(() => sevencode.value, (newVal) => {
  formData.value.entityType = cloneDeep(newVal)
}, { deep: true })

onMounted(() => {
  if (props.visible) {
    showDialog()
  }
})
</script>

<template>
  <el-drawer v-model="dialogVisible" direction="rtl" size="800" :show-close="false" :before-close="handleCloseTip"
    @close-auto-focus="closeDialog" @close="closeDialog">
    <template #header>
      <h4>编辑实体基本信息</h4>
    </template>
    <template #default>
      <el-form ref="formRef" :model="formData" :rules="formRules" :close-on-click-modal="false" label-width="85px"
        label-position="right" v-loading="detailLoading" element-loading-background="rgba(245, 247, 250, 0.8)">
        <el-row class="form-title">
          <div class="form-title-text">
            名称及描述
          </div>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item label="名称" prop="code">
              <el-input v-model="formData.code" placeholder="请输入" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="别名" prop="name">
              <el-input v-model="formData.name" placeholder="请输入" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="标签" prop="tag">
              <SelectTag module="entity" v-model:task_tags="formData.tag" :max-collapse-tags="2" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="描述" prop="description">
              <el-input v-model="formData.description" type="textarea" placeholder="请输入" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-row class="form-title sc">
          <div class="form-title-text">
            七类码
          </div>
          <div class="sc-input">
            <el-input-number v-model="sevencode.kind" :controls="false" class="sc-input-number center"
              @change="kindChange" />
            <span>.</span>
            <el-input-number v-model="sevencode.domain" :controls="false" class="sc-input-number center"
              @change="domainChange" />
            <span>.</span>
            <el-input-number v-model="sevencode.country" :controls="false" class="sc-input-number center"
              @change="countryChange" />
            <span>.</span>
            <el-input-number v-model="sevencode.category" :controls="false" class="sc-input-number center"
              @change="categoryChange" />
            <span>.</span>
            <el-input-number v-model="sevencode.subcategory" :controls="false" class="sc-input-number center"
              @change="subcategoryChange" />
            <span>.</span>
            <el-input-number v-model="sevencode.specific" :controls="false" class="sc-input-number center"
              @change="specificChange" />
            <span>.</span>
            <el-input-number v-model="sevencode.extra" :controls="false" class="sc-input-number center"
              @change="extraChange" />
          </div>
        </el-row>

        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item label="种类" prop="entityType.kind">
              <el-select v-model="sevencode.kind" popper-class="drawer-select-popper" placeholder="若无选项，默认值为-1"
                clearable @clear="() => sevencode.kind = -1" @change="kindChange" :loading="sevenCodeLoading.kind">
                <el-option v-for="item in kindOptions" :key="item.value" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="平台" prop="entityType.domain">
              <el-select v-model="sevencode.domain" popper-class="drawer-select-popper" placeholder="若无选项，默认值为-1"
                clearable @clear="() => sevencode.domain = -1" @change="domainChange" :loading="sevenCodeLoading.domain"
                :disabled="sevencode.kind === -1">
                <el-option v-for="item in domainOptions" :key="item.value" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="国家/地区" prop="entityType.country">
              <el-select v-model="sevencode.country" popper-class="drawer-select-popper" clearable
                @clear="() => sevencode.country = -1" @change="countryChange" :loading="sevenCodeLoading.country">
                <el-option v-for="item in countryOptions" :key="item.value" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="类别" prop="entityType.category">
              <el-select v-model="sevencode.category" popper-class="drawer-select-popper" clearable
                @clear="() => sevencode.category = -1" @change="categoryChange" :loading="sevenCodeLoading.category"
                :disabled="sevencode.country === -1">
                <el-option v-for="item in categoryOptions" :key="item.value" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="子类" prop="entityType.subcategory">
              <el-select v-model="sevencode.subcategory" popper-class="drawer-select-popper" clearable
                @clear="() => sevencode.subcategory = -1" @change="subcategoryChange"
                :loading="sevenCodeLoading.subcategory" :disabled="sevencode.category === -1">
                <el-option v-for="item in subCategoryOptions" :key="item.value" :label="item.name"
                  :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="具体型号" prop="entityType.specific">
              <el-select v-model="sevencode.specific" popper-class="drawer-select-popper" clearable
                @clear="() => sevencode.specific = -1" @change="specificChange" :loading="sevenCodeLoading.specific"
                :disabled="sevencode.subcategory === -1">
                <el-option v-for="item in specificOptions" :key="item.value" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="拓展型号" prop="entityType.extra">
              <el-select v-model="sevencode.extra" popper-class="drawer-select-popper" clearable
                @clear="() => sevencode.specific = -1" @change="extraChange" :loading="sevenCodeLoading.extra"
                :disabled="sevencode.specific === -1">
                <el-option v-for="item in extraOptions" :key="item.value" :label="item.name" :value="item.value" />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row :gutter="24">
          <el-col :span="12">
            <div class="form-title form-title-text">
              添加军标
            </div>
            <SelectMilstd class="stm-bg" v-model:selected-id="formData.milstdId" :entity-name="formData.code"
              accept=".jpg, .png, .jpeg" :id="formData.milstdId" v-model:path="formData.milstdPath"
              upload-type="milstd" />
          </el-col>
          <el-col :span="12">
            <div class="form-title form-title-text">
              添加三维模型
            </div>
            <SelectThree class="stm-bg" v-model:selected-id="formData.threeId" :entity-name="formData.code"
              accept=".glb, .fbx, .gltf, .obj, .stl, .3ds" :id="formData.threeId" v-model:path="formData.threePath"
              v-model:three-thumb-path="formData.threeThumbPath" upload-type="three-model" />
          </el-col>
        </el-row>
        <el-row :gutter="24">
          <el-col :span="12">
            <div class="form-title form-title-text" style="margin-top: 10px;">
              附件
            </div>
            <div>
              <el-upload class="again-upload" :show-file-list="true" :auto-upload="false"
                action="https://your-upload-api.com/upload" ref="upload" :file-list="insertFiles"
                accept=".zip, .pdf, .doc, .docx" :on-remove="handleRemove" :on-change="handleFileChange"
                :multiple="true">
                <el-button type="success">
                  添加附件
                </el-button>
              </el-upload>
            </div>
          </el-col>
        </el-row>
      </el-form>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button plain @click="closeDialog">
          取 消
        </el-button>
        <el-button :loading="loading" type="primary" @click="handleConfirm">
          确 定
        </el-button>
      </div>
    </template>
  </el-drawer>

  <div class="drawer-tag">
    <el-drawer v-model="drawer" :show-close="true" direction="rtl" size="700px" @close="closeDialogTag">
      <template #header>
        <h4>任务标签</h4>
      </template>
      <template #default>
        <div class="drawer-info-content" v-loading="tagLoading">
          <el-input v-if="tagList.length === 0" v-model="newTagInput" placeholder="请输入新标签" @keyup.enter="addNewTag">
            <template #append>
              <el-button @click="addNewTag">
                添加
              </el-button>
            </template>
          </el-input>

          <el-space wrap>
            <el-check-tag v-for="(item, index) in tagList" :key="index" @change="onChange(item)"
              :checked="formData.tag.includes(item.name)" class="mr10 custom-tag"
              :class="{ active: formData.tag.includes(item.name) }" size="small">
              {{ item.name }}
            </el-check-tag>
          </el-space>
        </div>
      </template>
    </el-drawer>
  </div>
</template>

<style lang="scss" scoped>
.form-title {
  margin-bottom: 18px;
}

.form-title-text {
  color: #fff;
  font-weight: 600;
}

.drawer-tag {
  .drawer-info-content {
    width: 100%;
    padding: 16px;

    :deep(.el-input) {
      width: 250px;
      margin-bottom: 16px;
    }
  }
}

.form-title.sc {
  display: flex;
  flex-direction: row;
  align-items: center;

  .sc-input {
    flex: 1;
    height: 34px;
    display: flex;
    flex-direction: row;
    align-items: start;
    background-color: rgb(4, 28, 51);
    border-radius: 4px;
    border: 1px solid #2a3555;
    gap: 10px;

    .el-input-number {
      width: calc(100% / 7);
    }

    span {
      height: 34px;
      line-height: 34px;
    }
  }

  .form-title-text {
    width: 85px;
  }
}

:deep(.sc-input-number) {
  &>.el-input>.el-input__wrapper {
    padding: 0px !important;
    border: none !important;
    box-shadow: none !important;

    &.is-focus {
      box-shadow: 0 0 0 1px var(--el-color-primary) !important;
    }
  }
}

.selectTag {
  margin-left: 8px;
}

.mr10 {
  margin-right: 10px;
  margin-bottom: 10px;
}

.custom-tag {
  cursor: pointer;
  transition: all 0.3s;

  &:hover {
    background-color: #ecf5ff;
  }

  &.active {
    color: #409eff;
    background-color: #d9ecff;
  }
}
</style>

<style lang="scss">
.stm-bg .show-content {
  background-color: #f3f3f3 !important;
}
</style>
